home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / sharew / packer / zlib / zfgetc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-17  |  6.3 KB  |  283 lines

  1. #include "zdef.h"
  2.  
  3. #include <proto.h>            /* for _PROTO macro... */
  4.  
  5. static void     decompress_more _PROTO((register ZFILE *z));
  6. static long     getcode _PROTO((register ZFILE *z));
  7.  
  8. #define CR        0x0D
  9. #define LF        0x0A
  10.  
  11. /*------------------------------*/
  12. /*    zfgetc            */
  13. /*------------------------------*/
  14. #ifndef __STDC__
  15. int zfgetc (z)
  16. ZFILE *z;
  17. #else
  18. int zfgetc (ZFILE *z)
  19. #endif
  20. {
  21.     int     c;
  22.  
  23.     /* 
  24.      *   If buffer empty, and not end-of-file, call decompress_more();
  25.      *   return next in buffer.  
  26.      */
  27. again:
  28.     if ((z->flags & NOT_COMPRESSED) != 0)
  29.     {
  30.         if ((c = z->c1) >= 0)
  31.         {
  32.             z->c1 = z->c2;
  33.             z->c2 = EOF;
  34.  
  35.             return ((int) c);
  36.         }
  37. again2:
  38.         c = fgetc (z->file);
  39. #ifdef ALCYON
  40.         /*
  41.          *   see note below...
  42.          */
  43.         if (c == CR)
  44.             goto again2;
  45. #endif
  46.         return ((int) c);
  47.     }
  48.     if ((z->bufget == z->bufput) && (!z->zeof))
  49.     {
  50.         decompress_more (z);
  51.     }
  52.     z->zeof = (z->bufput == z->bufget);
  53.     if (z->zeof)
  54.     {
  55.         if ((z->flags & ALLOCATED) != 0)
  56.         {
  57. #ifdef MSDOS
  58.             hfree (z->tab_suffixof);
  59.             hfree (z->tab_prefixof);
  60. #else
  61.             free (z->tab_suffixof);
  62.             free (z->tab_prefixof);
  63. #endif
  64.             z->flags &= (~ALLOCATED);
  65.         }
  66.         return ((int) EOF);
  67.     }
  68.     c = z->buff[z->bufget];
  69.     z->bufget++;
  70.  
  71. #ifdef MONITOR_CRLF
  72.     if (c == CR)
  73.         fprintf (stderr, "\n*** CR IN INPUT ***\n");
  74.     if (c == LF)
  75.         fprintf (stderr, "\n*** LF IN INPUT ***\n");
  76. #endif
  77.  
  78. #ifdef ALCYON
  79.     /*
  80.      *   at least with alcyon, fputc will write a cr-nl if c is nl so
  81.      *   skip past the cr we read. other libraries may or may not have
  82.      *   this problem...
  83.      */
  84.     if (c == CR)
  85.         goto again;
  86. #endif
  87.  
  88.     return ((int) c);
  89. }
  90.  
  91.  
  92.  
  93. /*------------------------------*/
  94. /*    decompress_more        */
  95. /*------------------------------*/
  96. #ifndef __STDC__
  97. static void decompress_more (z)
  98. register ZFILE *z;
  99. #else
  100. static void decompress_more (register ZFILE *z)
  101. #endif
  102. {
  103.     z->bufput = 0;
  104.     z->bufget = 0;
  105.  
  106.     if (z->init != 0)
  107.         goto resume;
  108.  
  109.     z->init   = 1;
  110.     z->offset = 0;
  111.     z->size   = 0;
  112.  
  113. #ifdef MSDOS
  114.     z->tab_suffixof =
  115.         (unsigned char PC_HUGE *) halloc (HSIZE, sizeof (unsigned char));
  116.     z->tab_prefixof =
  117.         (long PC_HUGE *) halloc (HSIZE, sizeof (long));
  118. #else
  119.     z->tab_suffixof =
  120.         (unsigned char *) malloc ((size_t) HSIZE * sizeof (unsigned char));
  121.     z->tab_prefixof = (long *) malloc ((size_t) HSIZE * sizeof (long));
  122. #endif
  123.     z->flags |= ALLOCATED;
  124.  
  125.     z->n_bits  = INIT_BITS;
  126.     z->maxcode = ((1L << (z->n_bits)) - 1L);
  127.     for (z->code = 255L; z->code >= 0L; z->code--)
  128.     {
  129.         z->tab_prefixof[z->code] = 0L;
  130.         z->tab_suffixof[z->code] = (unsigned char) z->code;
  131.     }
  132.     z->free_ent = ((z->block_compress) ? FIRST : 256L);
  133.  
  134.     z->finchar = z->oldcode = getcode (z);
  135.     if (z->oldcode == -1L)
  136.         return;            /* EOF already? */
  137.     if (z->finchar < 0L || z->finchar >= 256L)
  138.         fprintf (stderr, "****\n");
  139.     z->buff[z->bufput] = (char) (z->finchar & 0xff);
  140.     z->bufput++;
  141.  
  142.     z->stackp = 1L << Z_BITS;    /* The 1L is for DOS huge arrays */
  143.  
  144.     while ((z->code = getcode (z)) != EOF)
  145.     {
  146.         if ((z->code == CLEAR) && z->block_compress)
  147.         {
  148.             for (z->code = 255; z->code >= 0; z->code--)
  149.                 z->tab_prefixof[z->code] = 0;
  150.             z->clear_flg = 1;
  151.             z->free_ent  = FIRST - 1;
  152.             if ((z->code = getcode (z)) == EOF)
  153.                 break;    /* O, untimely death! */
  154.         }            /* if */
  155.         z->incode = z->code;
  156.         if (z->code >= z->free_ent)
  157.         {
  158.             z->tab_suffixof[z->stackp] = (unsigned char) z->finchar;
  159.             z->stackp                 += 1L;
  160.             z->code                    = z->oldcode;
  161.         }
  162.         while (z->code >= 256L)
  163.         {
  164.             z->tab_suffixof[z->stackp] = z->tab_suffixof[z->code];
  165.             z->stackp                 += 1L;
  166.             z->code                    = z->tab_prefixof[z->code];
  167.         }
  168.         z->finchar                 = z->tab_suffixof[z->code];
  169.         z->tab_suffixof[z->stackp] = (unsigned char) z->finchar;
  170.         z->stackp                 += 1L;
  171.         do
  172.         {
  173.             long    tmp;
  174.  
  175.             z->stackp           -= 1L;
  176.             tmp                  = z->tab_suffixof[z->stackp];
  177.             z->buff[z->bufput++] = (unsigned char) (tmp & 255L);
  178.             if (z->bufput == z->bufend)
  179.             {
  180.                 /*
  181.                  *   Logically a setjmp/longjump, but this
  182.                  *   is more portable
  183.                  */
  184.                 return;
  185.  
  186.                 /*
  187.                  *   jumped to here -- is jumping into a
  188.                  *   loop safe?
  189.                  *   - or should I use jumps for the loop too?
  190.                  */
  191. resume:                ;
  192.             }        /* if */
  193.  
  194.         } while (z->stackp > (1L << Z_BITS));
  195.         /* ^ This is why I changed stackp from a pointer. */
  196.         /* Pointer comparisons can be dubious...          */
  197.  
  198.         if ((z->code = z->free_ent) < (1L << z->maxbits))
  199.         {
  200.             z->tab_prefixof[z->code] = z->oldcode;
  201.             z->tab_suffixof[z->code] = (unsigned char) z->finchar;
  202.             z->free_ent              = z->code + 1;
  203.         }
  204.         z->oldcode = z->incode;
  205.     }                /* while */
  206. }
  207.  
  208. static unsigned char    rmask[9] =
  209. {
  210.     0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
  211. };
  212.  
  213.  
  214. /*------------------------------*/
  215. /*    getcode            */
  216. /*------------------------------*/
  217. #ifndef __STDC__
  218. static long getcode (z)
  219. register ZFILE *z;
  220. #else
  221. static long getcode (register ZFILE *z)
  222. #endif
  223. {                    /* Should be int!!! */
  224.     register long   code;
  225.     register long   r_off,
  226.                     bits;
  227.     register int    bp;
  228.  
  229.     bp = 0;
  230.     if (z->clear_flg != 0 || z->offset >= z->size
  231.     || z->free_ent > z->maxcode)
  232.     {
  233.         if (z->free_ent > z->maxcode)
  234.         {
  235.             z->n_bits++;
  236.             if (z->n_bits == z->maxbits)
  237.             {
  238.                 z->maxcode = (1L << z->maxbits);
  239.                 /* won't get any bigger now */
  240.             }
  241.             else
  242.             {
  243.                 z->maxcode = ((1L << (z->n_bits)) - 1L);
  244.             }
  245.         }
  246.         if (z->clear_flg != 0)
  247.         {
  248.             z->n_bits    = INIT_BITS;
  249.             z->maxcode   = ((1L << (z->n_bits)) - 1L);
  250.             z->clear_flg = 0;
  251.         }
  252.         z->size = fread (z->buf, 1, (size_t) z->n_bits, z->file);
  253.         if (z->size <= 0)
  254.         {
  255.             fclose (z->file);
  256.             return ((long) EOF);    /* end of file */
  257.         }
  258.         z->offset = 0;
  259.         z->size   = (z->size << 3) - (z->n_bits - 1);
  260.     }
  261.     r_off = z->offset;
  262.     bits  = z->n_bits;
  263.     bp    = bp + ((int) r_off >> 3);
  264.     r_off = r_off & 7;
  265.     code  = ((long) z->buf[bp++] >> r_off);
  266.     bits  = bits - 8 + r_off;
  267.     r_off = 8 - r_off;        /* now, offset into code word */
  268.     if (bits >= 8)
  269.     {
  270.         code  = code | ((long) z->buf[bp++] << r_off);
  271.         r_off = r_off + 8;
  272.         bits  = bits - 8;
  273.     }
  274.     code = code
  275.         | ((long) ((long) (z->buf[bp]) & (long) rmask[bits]) << (long) r_off);
  276.     z->offset = z->offset + z->n_bits;
  277.  
  278.     return ((long) code);
  279. }
  280.  
  281.  
  282.  
  283.